package com.jackrain.nea.ext.sequence.dao;

import com.jackrain.nea.core.redis.CusRedisTemplate;
import com.jackrain.nea.util.RedisOpsUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.stereotype.Repository;

/**
 * @author xubin
 * 2017-11-15
 */
@Repository
public class SequenceNumberDaoImpl implements SequenceNumberDao {


    @Autowired
    private RedisOpsUtil redisOpsUtil;

    private static String REDIS_KEY_PREFIX = "ext:sequence:current";
    private static String REDIS_INCR_PREFIX = "ext:sequence:increment";


    @Override
    public Long setStartNo(String sequenceName, String date, Long setValue, Long increment) {
        if (getIncreaseOperation(date, sequenceName).putIfAbsent(getKey(date, sequenceName), setValue.toString())) {
            return setValue;
        } else {
            return getIncreaseOperation(date, sequenceName).increment(getKey(date, sequenceName), increment);
        }
    }

    @Override
    public Long setAndIncrease(String sequenceName, String date, Long setValue, Long increment) {
        getIncreaseOperation(date, sequenceName).putIfAbsent(getKey(date, sequenceName), setValue.toString());
        return getIncreaseOperation(date, sequenceName).increment(getKey(date, sequenceName), increment);
    }

    @Override
    public Long increase(String sequenceName, String date, Long increment) {
        return getIncreaseOperation(date, sequenceName).increment(getKey(date, sequenceName), increment);
    }

    private static String getKey(String date, String sequenceName) {
        StringBuilder sb = new StringBuilder();
        sb.append(sequenceName);
        if (StringUtils.isNotBlank(date)) {
            sb.append(".").append(date);
        }
        return sb.toString();
    }

    private BoundHashOperations<String, String, String> getIncreaseOperation(String date, String sequenceName) {

        CusRedisTemplate<String, String> template = redisOpsUtil.strRedisTemplate;
        return template.boundHashOps(REDIS_INCR_PREFIX);
    }


}
